﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using Awesomium;
using Awesomium.Core;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Threading;
using System.Runtime.InteropServices;
using Awesomium.ComponentModel;
using Awesomium.Web;
using Awesomium.Windows;

namespace Diplomova_prace
{
    public class Exports
    {
        ProgressBar progressBar = new ProgressBar();
        Thread t = null;
        // nutné odřádkování !!!
        string xmlHeader = @"<?xml version='1.0' encoding='UTF-8'?>
";
        public string DivMain = Html.Div(Html.DivId);
        public void XML(string vstup, string path)
        {
            int EndHeader = 0;
            StreamWriter xml = null;
            StringBuilder sb = null;
            SetTitleProgress("Vytvářím XML...");
            if (t == null || !t.IsAlive)
            {
                t = new Thread(new ThreadStart(progressBar.ShowWindow));
                t.Start();
            }
            ListHtmlTags lst = new ListHtmlTags();
            var fields = lst.GetType().GetFields().Select(field => field.GetValue(lst)).ToList();
            EndHeader = vstup.IndexOf(DivMain);
            vstup = vstup.Remove(0, EndHeader);
            vstup = vstup.Replace(Html.EndHTML, string.Empty);
            for (int i = 0; i < fields.Count; i++)
            {
                if (fields[i].ToString() != "span")
                    foreach (Match match in Regex.Matches(vstup, "</?" + fields[i] + "+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>"))
                    {
                        string shoda = match.ToString();
                        vstup = vstup.Replace(shoda, string.Empty);
                    }
            }
            vstup = vstup.Replace("span " + Html.SpanId, "mtext");
            vstup = vstup.Replace("/span", "/mtext");
            sb = new StringBuilder(xmlHeader + Mathml.HeaderMath());
            sb.Append(vstup);
            sb.Append(Mathml.EndMath);
            xml = new StreamWriter(path);
            xml.WriteLine(sb.ToString());
            xml.Close();
            try
            {
                t.Abort();
                t = null;
            }
            catch (ThreadAbortException e)
            {
                MessageBox.Show(e.ToString());
            }

        }
        public void HTML(string vstup, string path)
        {
            StreamWriter html = new StreamWriter(path);
            SetTitleProgress("Vytvářím HMTL...");
            if (t == null || !t.IsAlive)
            {
                t = new Thread(new ThreadStart(progressBar.ShowWindow));
                t.Start();
            }
            vstup = vstup.Replace(Html.javaScript, "");    
            html.WriteLine(vstup);
            html.Close();
            try
            {
                t.Abort();
                t = null;
            }
            catch (ThreadAbortException e)
            {
                MessageBox.Show(e.ToString());
            }
        }
        public void Image(string input, string destination, int width, int height, ImageFormat format, int fontSize)
        {
            const int maxsize = 15000;
            string pathTempHtml = string.Empty;
            string ext = string.Empty;
            string tempdst = string.Empty;
            SetTitleProgress("Vytvářím "+format.ToString().ToUpper()+ "...");
            if (t == null || !t.IsAlive)
            {
                t = new Thread(new ThreadStart(progressBar.ShowWindow));
                t.Start();
            }
            height = 0;
            pathTempHtml = Directory.GetCurrentDirectory() + "\\" + MainMenu.imgProperty + Path.GetFileName(destination) +".html";
            input = NewHeader(input, width, height, fontSize, false);
            SaveTempHTML(input, pathTempHtml);
            Tuple<bool, int, int, int> webview = WebViewLoad(width, height, pathTempHtml, maxsize, maxsize, destination, fontSize, false);
            while (!webview.Item1)
            {
                input = NewHeader( input, webview.Item2, webview.Item3, webview.Item4, false);
                SaveTempHTML(input, pathTempHtml);
                webview = WebViewLoad(webview.Item2, webview.Item3, pathTempHtml, maxsize, maxsize, destination, webview.Item4, false);
            }
            input = NewHeader(input, webview.Item2, webview.Item3, webview.Item4, false);
            SaveTempHTML(input, pathTempHtml);
            WebViewLoad(webview.Item2, webview.Item3, pathTempHtml, maxsize, maxsize, destination, webview.Item4, false);

            ext = Path.GetExtension(destination);
            destination = destination.Substring(0, destination.Length - ext.Length);
        
            tempdst = destination + MainMenu.tempProperty+ext;
            System.Drawing.Image image = null;
            while (!File.Exists(tempdst))
            {
            }
            if (File.Exists(tempdst))
                image = System.Drawing.Image.FromFile(tempdst);
            if (ext == ".jpg" || ext == ".jpeg")
            {
                ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
                System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.Quality;
                EncoderParameters pars = new EncoderParameters(1);
                EncoderParameter par = new EncoderParameter(encoder, 100L);
                pars.Param[0] = par;
                image.Save(destination + ext, myImageCodecInfo, pars);
            }
            else
                image.Save(destination + ext, format);
            image.Dispose();
            File.Delete(destination + MainMenu.tempProperty + ext);
            try
            {
                t.Abort();
                t = null;
            }
            catch (ThreadAbortException e)
            {
                MessageBox.Show(e.ToString());
            }
        }    
        public void PDF(string input, string destination, int width, int height, int fontSize)
        {
            const int maxsizeh = 596;
            const int maxsizew = 842;
            string pathTempHtml = string.Empty;
            SetTitleProgress("Vytvářím PDF...");
            if (t == null || !t.IsAlive)
            {
                t = new Thread(new ThreadStart(progressBar.ShowWindow));
                t.Start();
            }
            pathTempHtml = Directory.GetCurrentDirectory() + "\\" + MainMenu.imgProperty + Path.GetFileName(destination) + ".html";
            input = NewHeader( input, width, height, fontSize, false);
            SaveTempHTML(input, pathTempHtml);
            Tuple<bool, int, int, int> webview = WebViewLoad(width, height, pathTempHtml, maxsizeh, maxsizew, destination, fontSize, true);
            input = NewHeader(input, webview.Item2, webview.Item3, webview.Item4, false);
            SaveTempHTML(input, pathTempHtml);
            webview = WebViewLoad(webview.Item2, webview.Item3, pathTempHtml, maxsizeh, maxsizew, destination, webview.Item4, true, true);
            File.Delete(pathTempHtml);
            try
            {
                t.Abort();
                t = null;
            }
            catch (ThreadAbortException e)
            {
                MessageBox.Show(e.ToString());
            }
        }
        private Tuple<bool, int, int, int> WebViewLoad(int width, int height, string pathTempHtml, int maxsizeh, int maxsizew, string destination, int fontSize, bool pdf,bool print =false)
        {
            int padding = 70;
            int cnt = 0;
            string ext = string.Empty;
            string isCompleted = string.Empty;
          
            WebView vw = WebCore.CreateWebView(width + padding, height + padding);
            using (vw = WebCore.CreateWebView(width + padding, height + padding))
            {
                vw.Source = new Uri(Path.GetFullPath(pathTempHtml));
                while (vw.IsLoading || !vw.IsDocumentReady)
                {
                    WebCore.Update();
                }
                isCompleted = vw.ExecuteJavascriptWithResult("IsCompleted()");
                while (isCompleted != "true" || cnt < 2)
                {
                   
                    isCompleted = vw.ExecuteJavascriptWithResult("IsCompleted()");
                    if (isCompleted == "true")
                        cnt++;
                }
                width = int.Parse(vw.ExecuteJavascriptWithResult("WidthDiv()"));
                height = int.Parse(vw.ExecuteJavascriptWithResult("HeightDiv()"));
                vw.Resize(width, height);
                
                if (!pdf)
                {
                    if (((double)height / (double)width >= 2.0))
                    {
                        if (fontSize > 10)
                        {
                            int sqr = height * width;
                            height = width = (int)Math.Floor(Math.Sqrt(sqr)) - padding;
                            vw.Dispose();
                            return Tuple.Create(false, width, height, fontSize - 2);
                        }
                    }
                }
                ext = Path.GetExtension(destination);
                destination = destination.Substring(0, destination.Length - Path.GetExtension(destination).Length);
                if (!pdf)
                {
                    ((BitmapSurface)vw.Surface).SaveToPNG(destination + "temp"+ext);
                }
                else
                {
                    if(print)
                    {
                        PrintConfig prc = new PrintConfig();
                        prc.PageSize = new AweRect(0, 0, maxsizeh, maxsizew);
                        vw.PrintToFile(Directory.GetCurrentDirectory(), prc);
                        while (vw.IsPrinting)
                            WebCore.Update();
                    }
                }
                vw.Dispose();
                
                return Tuple.Create(true, width, height, fontSize);
                
            }
        }
        private string NewHeader(string input, int width, int height, int fontSize, bool svgOutput)
        {
            int EndHeader = 0;
            int FirstEndBracket = 0;
            string head = string.Empty;
            Match match = null;
            EndHeader = input.IndexOf(DivMain);
            input = input.Remove(0, EndHeader);
            FirstEndBracket = input.IndexOf(">");
            input = input.Remove(0, FirstEndBracket + 1);
            head = Html.HeaderHTML(string.Empty, "messageStyle: 'none',");
            match = Regex.Match(head, "font-size:\\s*[0-9]*px");
            head = head.Replace(match.ToString(), string.Empty);
            head = head.Replace("#" + Html.MainDiv + "{", "#" + Html.MainDiv + "{width:" + width + "px !important;height:" + height + "px !important; font-size:" + fontSize + "px;");
            if (svgOutput)
            {
                head = head.Replace(Html.MathmlConfigure, Html.SvgConfigure);
                head = head.Replace(Html.HtmlLinebreaking, Html.SvgLinebreaking);
            }
            return head + input;
        }
        private static ImageCodecInfo GetEncoderInfo(String mimeType)
        {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
        }
        private void SetTitleProgress(string name)
        {
            progressBar.Text = name;
        }
        private void SaveTempHTML(string input, string pathToHtml)
        {
            StreamWriter sw = new StreamWriter(pathToHtml);
            sw.WriteLine(input);
            sw.Close();
        }

    }
}
